﻿
#define _CRT_SECURE_NO_WARNINGS

#if __linux__
#include <unistd.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>

#include "base_type.h"

//#include "sds_def.h"
#include "video_ps.h"


void  rgb2yuv422Packed(unsigned char rgbData[1280*720*3], unsigned short yuvData[1280*720])
{
    int i,j,temp;
    int index = 0;
    unsigned char bsetU;
    unsigned char y_temp;
    unsigned char uv_temp;
    int height = 720;
    int width = 1280;
    int widthstep = 1280*3;
    j = 0;
    //printf("hello,world2!\n");
    for (i=0;i<height;i++)
    {
        bsetU = 1;
        //printf("height = %d\n",i);
        for (j=0;j<width;j++)
        {
            unsigned char b = rgbData[i*widthstep+3*j];
            unsigned char g = rgbData[i*widthstep+3*j+1];
            unsigned char r = rgbData[i*widthstep+3*j+2];
            // printf("hello,world2!\n");
            temp =(int)GetY(r,g,b);
            y_temp = (temp<0)?0:((temp>255)?255:temp);
            if (1 == bsetU) //
            {
				// 0 1
				// U Y
                temp = (int)GetU(r,g,b);
                uv_temp = (temp<0)?0:((temp>255)?255:temp);
                yuvData[index++] = (unsigned short)(uv_temp) + (unsigned short)(y_temp << 8);
                //yuvData[index++] = (unsigned short)(YUV_BLACK_VAL) + (unsigned short)(y_temp << 8);

                //printf("hello,world3!\n");
                bsetU = 0;
            }
            else
            {
				// 3 4
				// V Y 
                temp = (int)GetV(r,g,b);
                uv_temp = (temp<0)?0:((temp>255)?255:temp);
                yuvData[index++] = (unsigned short)(uv_temp) + (unsigned short)(y_temp << 8);
                //yuvData[index++] = (unsigned short)(YUV_BLACK_VAL) + (unsigned short)(y_temp << 8);
                bsetU = 1;
            }
        }
    }

}

unsigned char* clLoadImage(char* path)
{
    unsigned char* bmpImg;

    FILE* pFile;
    unsigned short fileType;
    ClBitMapFileHeader bmpFileHeader;
    ClBitMapInfoHeader bmpInfoHeader;
    int channels = 1;
    int width = 0;
    int height = 0;
    int step = 0;
    int offset = 0;
    unsigned char pixVal;
    ClRgbQuad* quad;
    int i, j, k = 0;

    bmpImg = (unsigned char*)malloc(1280*720*3*sizeof(char));
    printf("bmpImg pointer == 0x%p\n! \n",bmpImg);
    pFile = fopen(path, "rb");
    if (!pFile)
    {
    	printf("open bmp failed !\n");
        free(bmpImg);
        //return NULL;
    }

    fread(&fileType, sizeof(unsigned short), 1, pFile);
    if (fileType == 0x4D42)
    {
        printf("%s,%d, bmp file! \n", __FILE__, __LINE__);

        fread(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
        printf("===================================================\n");
        printf("bmp head:\n");
        printf("bfSize%lu:\n", bmpFileHeader.bfSize);
        printf("bfReserved1:%u \n", bmpFileHeader.bfReserved1);
        printf("bfReserved2:%u \n", bmpFileHeader.bfReserved2);
        printf("bfOffBits:%lu \n", bmpFileHeader.bfOffBits);

        fread(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
        printf("===================================================\n");
        printf("bmpInfoHeader:\n");
        printf("biSize:%lu \n", bmpInfoHeader.biSize);
        printf("biWidth:%lu \n", bmpInfoHeader.biWidth);
        printf("biHeight:%lu \n", bmpInfoHeader.biHeight);
        printf("biPlanes:%d \n", bmpInfoHeader.biPlanes);
        printf("biBitCount:%d \n", bmpInfoHeader.biBitCount);
        printf("biCompression:%lu \n", bmpInfoHeader.biCompression);
        printf("biSizeImage:%lu \n", bmpInfoHeader.biSizeImage);
        printf("biXPelsPerMeter:%lu \n", bmpInfoHeader.biXPelsPerMeter);
        printf("biYPelsPerMeter:%lu \n", bmpInfoHeader.biYPelsPerMeter);
        printf("biClrUsed:%lu \n", bmpInfoHeader.biClrUsed);
        printf("biClrImportant:%lu \n", bmpInfoHeader.biClrImportant);
        printf("===================================================\n\n");

        if (bmpInfoHeader.biBitCount == 8)
        {
            //printf("该文件有调色板，即该位图为非真彩色\n\n");
            channels = 1;
            width = bmpInfoHeader.biWidth;
            height = bmpInfoHeader.biHeight;
            offset = (channels*width)%4;
            if (offset != 0)
            {
                offset = 4 - offset;
            }
            //bmpImg->mat = kzCreateMat(height, width, 1, 0);
            //bmpImg->width = width;
            //bmpImg->height = height;

            //bmpImg->imageData = (unsigned char*)sds_alloc(sizeof(unsigned char)*width*height);
            step = channels*width;

            quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad)*256);
            fread(quad, sizeof(ClRgbQuad), 256, pFile);
            free(quad);

            for (i=0; i<height; i++)
            {
                for (j=0; j<width; j++)
                {
                    fread(&pixVal, sizeof(unsigned char), 1, pFile);
                    bmpImg[(height-1-i)*step+j*3+k]= pixVal;
                }
                if (offset != 0)
                {
                    for (j=0; j<offset; j++)
                    {
                        fread(&pixVal, sizeof(unsigned char), 1, pFile);
                    }
                }
            }
        }
        else if (bmpInfoHeader.biBitCount == 24)
        {
            printf("%s,%d, ture color!\n\n", __FILE__, __LINE__);

            channels = 3;
            width = bmpInfoHeader.biWidth;
            height = bmpInfoHeader.biHeight;
            step = channels*width;
            offset = (channels*width)%4;

			printf("%s,%d, coming here2!\n\n", __FILE__, __LINE__);
            if (offset != 0)
            {
                offset = 4 - offset;
            }
            printf("%s,%d, coming here1!\n\n", __FILE__, __LINE__);
            for (i=0; i<height; i++)
            {
                for (j=0; j<width; j++)
                {
                    for (k=0; k<3; k++)
                    {
                        fread(&pixVal, sizeof(unsigned char), 1, pFile);
						//printf("coming here2!\n\n");
                        bmpImg[(height-1-i)*step+j*3+k]= pixVal;
						//printf("coming here3!\n\n");
                    }
                    //kzSetMat(bmpImg->mat, height-1-i, j, kzScalar(pixVal[0], pixVal[1], pixVal[2]));
                }
                if (offset != 0)
                {
                    for (j=0; j<offset; j++)
                    {
                        fread(&pixVal, sizeof(unsigned char), 1, pFile);
                    }
                }
            }
        }
    }

    return bmpImg;
}

#if 0
unsigned char sobel_operator(unsigned char window[SOBEL_SIZE][SOBEL_SIZE])
{
  short x_weight = 0;
  short y_weight = 0;

  short edge_weight;
  unsigned char edge_val;

  int i;
  int j;

  const short x_op[SOBEL_SIZE][SOBEL_SIZE] = { {-1,0,1},
                             {-2,0,2},
                             {-1,0,1}};

  const short y_op[SOBEL_SIZE][SOBEL_SIZE] = { {1,2,1},
                             {0,0,0},
                             {-1,-2,-1}};

  //Compute approximation of the gradients in the X-Y direction
  for(i=0; i < SOBEL_SIZE; i++){
    for(j = 0; j < SOBEL_SIZE; j++){

      // X direction gradient
      x_weight = x_weight + window[i][j] * x_op[i][j];

      // Y direction gradient
      y_weight = y_weight + window[i][j] * y_op[i][j];
    }
  }

  edge_weight = abs(x_weight) + abs(y_weight);

  //Edge thresholding
  if(edge_weight > 200)
    edge_weight = 255;
  else if(edge_weight < 100)
    edge_weight = 0;
  edge_val = (unsigned char)edge_weight;

  return edge_val;
}

#pragma SDS data access_pattern(yc_in:SEQUENTIAL)
#pragma SDS data access_pattern(yc_out:SEQUENTIAL)
void sobel_filter(unsigned short yc_in[NUMROWS*NUMCOLS],unsigned short yc_out[NUMROWS*NUMCOLS])
{
//#pragma AP INTERFACE ap_fifo port=yc_in
//#pragma AP INTERFACE ap_fifo port=yc_out

  int row;
  int col;
  char i;
  char j;

  //定义输入buffer，3行
  short buff_A[SOBEL_SIZE][NUMCOLS];
  //定义需要处理的图像窗口
  unsigned char buff_C[SOBEL_SIZE][SOBEL_SIZE];

  for(row = 0; row < NUMROWS; row++){
    for(col = 0; col < NUMCOLS; col++){
#pragma AP PIPELINE II = 1

      // Temp values are used to reduce the number of memory reads
      unsigned short input_data = 0;
      unsigned char temp = 0;
      unsigned char tempx = 0;

      //填充line buffer，图像像素按照streaming的格式进入，依次填入line buffer
      if(col < NUMCOLS) {
	  	for(i = 1; i < 3; i ++)
	  		{
            buff_A[i][col] = buff_A[i-1][col];
		    }
        temp = buff_A[0][col];
      }

      //填充最新的数据
      if((col < NUMCOLS) & (row < NUMROWS)) {
        unsigned char y;
        input_data = yc_in[row*NUMCOLS+col];
        y = input_data >> BYTESHIFT ;
        tempx = y;
        buff_A[0][col] = tempx;
      }

      //移动图像窗口
      for(i = 0; i < 3; i++)
      	{
        for(j = 0; j < 2;j++)
        	{
            buff_C[i][j] = buff_C[i][j+1];
		    }
	    }

      //填充由于移动空出来的窗口
      if(col < NUMCOLS) {
	  	buff_C[0][2] = buff_A[2][col];
        buff_C[1][2] = temp;
		buff_C[2][2] = tempx;
      }

      unsigned char edge;
      //The sobel operator only works on the inner part of the image
      //This design assumes there are no edges on the boundary of the image
      if( row <= 1 || col <= 1 || row > (NUMROWS-1) || col > (NUMCOLS-1)) {
        edge=0;
      }
      else {
        //Sobel operation on the inner portion of the image
        edge = sobel_operator(&buff_C);
      }

      //The output image is offset from the input to account for the line buffer
      yc_out[row*NUMCOLS+col] = (short)((edge << BYTESHIFT) | YUV_BLACK_VAL);
      }
    }
  }

void sobel_filter_compare(unsigned short yc_in[NUMROWS*NUMCOLS],unsigned short yc_out[NUMROWS*NUMCOLS])
{
//#pragma AP INTERFACE ap_fifo port=yc_in
//#pragma AP INTERFACE ap_fifo port=yc_out

  int row;
  int col;
  char i;
  char j;

  //定义输入buffer，3行
  short buff_A[SOBEL_SIZE][NUMCOLS];
  //定义需要处理的图像窗口
  unsigned char buff_C[SOBEL_SIZE][SOBEL_SIZE];

  for(row = 0; row < NUMROWS; row++){
    for(col = 0; col < NUMCOLS; col++){
#pragma AP PIPELINE II = 1

      // Temp values are used to reduce the number of memory reads
      unsigned short input_data = 0;
      unsigned char temp = 0;
      unsigned char tempx = 0;

      //填充line buffer，图像像素按照streaming的格式进入，依次填入line buffer
      if(col < NUMCOLS) {
	  	for(i = 1; i < 3; i ++)
	  		{
            buff_A[i][col] = buff_A[i-1][col];
		    }
        temp = buff_A[0][col];
      }

      //填充最新的数据
      if((col < NUMCOLS) & (row < NUMROWS)) {
        unsigned char y;
        input_data = yc_in[row*NUMCOLS+col];
        y = input_data >> BYTESHIFT ;
        tempx = y;
        buff_A[0][col] = tempx;
      }

      //移动图像窗口
      for(i = 0; i < 3; i++)
      	{
        for(j = 0; j < 2;j++)
        	{
            buff_C[i][j] = buff_C[i][j+1];
		    }
	    }

      //填充由于移动空出来的窗口
      if(col < NUMCOLS) {
	  	buff_C[0][2] = buff_A[2][col];
        buff_C[1][2] = temp;
		buff_C[2][2] = tempx;
      }

      unsigned char edge;
      //The sobel operator only works on the inner part of the image
      //This design assumes there are no edges on the boundary of the image
      if( row <= 1 || col <= 1 || row > (NUMROWS-1) || col > (NUMCOLS-1)) {
        edge=0;
      }
      else {
        //Sobel operation on the inner portion of the image
        edge = sobel_operator(&buff_C);
      }

      //The output image is offset from the input to account for the line buffer
      yc_out[row*NUMCOLS+col] = (short)((edge << BYTESHIFT) | YUV_BLACK_VAL);
      }
    }
  }


#endif
